View Javadoc
1   package edu.jiangxin.apktoolbox.file.core;
2   
3   import java.io.BufferedReader;
4   import java.io.BufferedWriter;
5   import java.io.File;
6   import java.io.FileInputStream;
7   import java.io.FileOutputStream;
8   import java.io.InputStreamReader;
9   import java.io.OutputStreamWriter;
10  import java.nio.charset.StandardCharsets;
11  import java.util.Collection;
12  import java.util.Iterator;
13  import java.util.List;
14  
15  import org.apache.commons.io.FileUtils;
16  import org.apache.commons.lang3.StringUtils;
17  import org.apache.logging.log4j.LogManager;
18  import org.apache.logging.log4j.Logger;
19  
20  /**
21   * 不同操作系统文件格式转换
22   * 
23   * @author jiangxin
24   * @author 2018-09-09
25   */
26  public class OsPatternConvert {
27  
28      private static final Logger logger = LogManager.getLogger(OsPatternConvert.class.getSimpleName());
29  
30      /**
31       * 不同操作系统文件格式之间的转换.
32       * <p style="text-indent:2em">
33       * 转换函数的真正实现函数,其它转换函数必须调用此函数。
34       * </p>
35       * 
36       * @param srcFileString             源文件的文件名
37       * @param desFileString             目标文件的文件名
38       * @param options:换行符,比如:\n,\r,\r\n
39       */
40      private static void convert(String srcFileString, String desFileString, String options) {
41  
42          // 临时文件的后缀名,尽量保证不会含有同名文件
43          String special = ".OSPattenConvert.temp";
44          // 如果源文件和目标文件相同(包括路径),则使用临时文件进行转换
45          if (srcFileString.equals(desFileString)) {
46              srcFileString = srcFileString + special;
47              FileProcess.copyFile(desFileString, srcFileString);
48          }
49          File srcFileFile = new File(srcFileString);
50          File desFileFile = new File(desFileString);
51  
52          // 判断源文件是否存在
53          if (!srcFileFile.exists()) {
54              System.out.println("源文件不存在:" + srcFileFile.getAbsolutePath());
55              return;
56          }
57          // 判断目标文件是否存在
58          if (!desFileFile.getParentFile().exists()) {
59              boolean ret = desFileFile.getParentFile().mkdirs();
60              if (!ret) {
61                  logger.error("mkdirs failed: " + desFileFile.getParentFile());
62              }
63          }
64  
65          // 仅支持UTF-8编码
66          try (BufferedReader reader = new BufferedReader(
67                  new InputStreamReader(new FileInputStream(srcFileFile), StandardCharsets.UTF_8));
68                  BufferedWriter writer = new BufferedWriter(
69                          new OutputStreamWriter(new FileOutputStream(desFileFile), StandardCharsets.UTF_8))) {
70              String temp = null;
71              while ((temp = reader.readLine()) != null) {
72                  writer.write(temp);
73                  writer.write(options);
74              }
75          } catch (Exception e) {
76              logger.error("Exception", e);
77          }
78  
79          // 如果存在临时文件,则删除
80          if (srcFileString.equals(desFileString + special)) {
81              boolean ret = srcFileFile.delete();
82              if (!ret) {
83                  logger.error("delete tmp file failed: " + srcFileFile);
84              }
85          }
86      }
87  
88      /**
89       * 其它操作系统文件格式转换成Unix文件格式.
90       * 
91       * @param srcFileString 转换前的文件
92       * @param desFileString 转换后的文件
93       */
94      private static void toUnix(String srcFileString, String desFileString) {
95          convert(srcFileString, desFileString, "\n");
96          logger.info("Success to convert {} to unix", srcFileString);
97      }
98  
99      /**
100      * 其它操作系统文件格式转换成Dos文件格式.
101      * 
102      * @param srcFileString 转换前的文件
103      * @param desFileString 转换后的文件
104      */
105     private static void toDos(String srcFileString, String desFileString) {
106         convert(srcFileString, desFileString, "\r\n");
107         logger.info("Success to convert {} to dos", srcFileString);
108     }
109 
110     /**
111      * 其它操作系统文件格式转换成Mac文件格式.
112      * 
113      * @param srcFileString 转换前的文件
114      * @param desFileString 转换后的文件
115      */
116     private static void toMac(String srcFileString, String desFileString) {
117         convert(srcFileString, desFileString, "\r");
118         logger.info("Success to convert {} to mac", srcFileString);
119     }
120 
121     /**
122      * Dos文件格式转换成Unix文件格式.
123      * 
124      * @param srcFileString 转换前的文件
125      * @param desFileString 转换后的文件
126      */
127     public static void dos2Unix(String srcFileString, String desFileString) {
128         toUnix(srcFileString, desFileString);
129     }
130 
131     /**
132      * Dos文件格式转换成Mac文件格式.
133      * 
134      * @param srcFileString 转换前的文件
135      * @param desFileString 转换后的文件
136      */
137     public static void dos2Mac(String srcFileString, String desFileString) {
138         toMac(srcFileString, desFileString);
139     }
140 
141     /**
142      * Unix文件格式转换成Dos文件格式.
143      * 
144      * @param srcFileString 转换前的文件
145      * @param desFileString 转换后的文件
146      */
147     public static void unix2Dos(String srcFileString, String desFileString) {
148         toDos(srcFileString, desFileString);
149     }
150 
151     /**
152      * Unix文件格式转换成Mac文件格式.
153      * 
154      * @param srcFileString 转换前的文件
155      * @param desFileString 转换后的文件
156      */
157     public static void unix2Mac(String srcFileString, String desFileString) {
158         toMac(srcFileString, desFileString);
159     }
160 
161     /**
162      * Mac文件格式转换成Unix文件格式.
163      * 
164      * @param srcFileString 转换前的文件
165      * @param desFileString 转换后的文件
166      */
167     public static void mac2Unix(String srcFileString, String desFileString) {
168         toUnix(srcFileString, desFileString);
169     }
170 
171     /**
172      * Mac文件格式转换成Dos文件格式.
173      * 
174      * @param srcFileString 转换前的文件
175      * @param desFileString 转换后的文件
176      */
177     public static void mac2Dos(String srcFileString, String desFileString) {
178         toDos(srcFileString, desFileString);
179     }
180 
181     /**
182      * 不同操作系统文件格式之间的转换.
183      * <p style="text-indent:2em">
184      * 从一个操作系统文件格式转向另一个,转换模式有patter指定,pattern的格式为:
185      * </p>
186      * <p style="text-indent:4em">
187      * os_a2os_b os_a和os_b的可能取值为linux/dos/windows/mac/unix/bsd等
188      * </p>
189      * 
190      * @param srcFileString 转换前的文件
191      * @param desFileString 转换后的文件
192      * @param pattern       转换模式
193      */
194     public static void osFileConvert(String srcFileString, String desFileString, String pattern) {
195 
196         // 允许输入大写字母格式的转换模式
197         pattern = pattern.toLowerCase();
198         // 替换pattern中的to,防止误输入
199         pattern = pattern.replace("to", "2");
200         // 由于linux和unix文件格式相同,所以直接用unix替换linux,但会产生unix2unix类型
201         pattern = pattern.replace("linux", "unix");
202         // 由于bsd和unix文件格式相同,所以直接用unix替换linux,但会产生unix2unix类型
203         pattern = pattern.replace("bsd", "unix");
204         // 由于windows和dos文件格式相同,所以直接用unix替换linux,但会产生dos2dos类型
205         pattern = pattern.replace("windows", "dos");
206         boolean isToUnix = "2unix".equals(pattern) || "mac2unix".equals(pattern) || "dos2unix".equals(pattern)
207                 || "unix2unix".equals(pattern);
208         boolean isToMac = "2mac".equals(pattern) || "dos2mac".equals(pattern) || "unix2mac".equals(pattern);
209         boolean isToDos = "2dos".equals(pattern) || "mac2dos".equals(pattern) || "unix2dos".equals(pattern)
210                 || "dos2dos".equals(pattern);
211 
212         if (isToUnix) {
213             toUnix(srcFileString, desFileString);
214         } else if (isToDos) {
215             toDos(srcFileString, desFileString);
216         } else if (isToMac) {
217             toMac(srcFileString, desFileString);
218         } else {
219             System.err.println("Error input,can't convert!");
220         }
221     }
222 
223     /**
224      * 不同操作系统文件格式之间的转换.
225      * <p style="text-indent:2em">
226      * 从一个操作系统文件格式转向另一个,转换模式有patter指定,pattern的格式为:
227      * </p>
228      * <p style="text-indent:4em">
229      * os_a2os_b os_a和os_b的可能取值为linux/dos/windows/mac/unix/bsd等
230      * </p>
231      * 
232      * @param fileString 需要转换的文件
233      * @param pattern    转换模式
234      * @see #osFileConvert(String, String, String)
235      */
236     public static void osFileConvert(String fileString, String pattern) {
237         osFileConvert(fileString, fileString, pattern);
238     }
239 
240     /**
241      * 不同操作系统文件格式之间的转换.
242      * <p style="text-indent:2em">
243      * 转换的对象为指定目录中的所有以后缀suffix指定的文件
244      * </p>
245      * 
246      * @param srcDirString 要求转换的目录
247      * @param desDirString 转化后要存放的目录
248      * @param pattern      转换模式
249      * @see #osFileConvert(String, String, String)
250      * @param suffix 过滤特定文件后缀
251      */
252     public static void osDirConvert(String srcDirString, String desDirString, String pattern, String suffix) {
253         File srcDirFile = new File(srcDirString);
254         File desDirFile = new File(desDirString);
255         if (!srcDirFile.exists()) {
256             System.out.println("源目录不存在" + srcDirFile.getAbsolutePath());
257         }
258         String[] extensions = null;
259         if (StringUtils.isNotEmpty(suffix)) {
260             extensions = suffix.split(",");
261         }
262         Collection<File> arrayList = FileUtils.listFiles(srcDirFile, extensions, true);
263         Iterator<File> it = arrayList.iterator();
264         while (it.hasNext()) {
265             File srcFileFile = it.next();
266             // 得到源文件绝对地址
267             String srcFileString = srcFileFile.getAbsolutePath();
268             String temp = srcFileFile.getAbsolutePath().substring(srcDirFile.getAbsolutePath().length());
269             // 得到目标文件绝对地址
270             String desFileString = desDirFile.getAbsolutePath() + temp;
271             osFileConvert(srcFileString, desFileString, pattern);
272         }
273 
274     }
275 
276     /**
277      * 不同操作系统文件格式之间的转换.
278      * <p style="text-indent:2em">
279      * 转换的对象为指定目录中的所有文件
280      * </p>
281      * 
282      * @param srcDirString 要求转换的目录
283      * @param desDirString 转化后要存放的目录
284      * @param pattern      转换模式
285      * @see #osFileConvert(String, String, String)
286      */
287     public static void osDirConvert(String srcDirString, String desDirString, String pattern) {
288         osDirConvert(srcDirString, desDirString, pattern, null);
289     }
290 
291     /**
292      * 不同操作系统文件格式之间的转换.
293      * <p style="text-indent:2em">
294      * 转换的对象为文件列表
295      * </p>
296      * 
297      * @param files   要转换是文件列表
298      * @param pattern 转换模式
299      * @see #osFileConvert(String, String, String)
300      */
301     public static void osConvertFiles(List<File> files, String pattern) {
302         Iterator<File> it = files.iterator();
303         while (it.hasNext()) {
304             osFileConvert(it.next().getAbsolutePath(), pattern);
305         }
306     }
307 
308 }